﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
// Qt headers
#include <QPainter>
#include <QApplication>
#include <QImage>
#include <QMouseEvent>

// custom headers
#include "ProjectComponentsTableHeaderView.h"
#include "ProjectComponentsTableSymbols.h"
#include "AppService.h"
#include "PaintingUtils.h"
#include "DebugMessage.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 
namespace gmepgcs
{
    ProjectComponentsTableHeaderView::ProjectComponentsTableHeaderView(Qt::Orientation orientation, QWidget *parent)
        : QHeaderView(orientation, parent),
        m_checkState(Qt::CheckState::Unchecked),
        m_bMousePressedOnCheckBox(false),
        m_isEditOperationVisible(true)
    {

    }

    ProjectComponentsTableHeaderView::~ProjectComponentsTableHeaderView()
    {
    }

    void ProjectComponentsTableHeaderView::SetIsEditOperationVisible(bool isEditOperationVisible/* = true*/)
    {
        m_isEditOperationVisible = isEditOperationVisible;
    }

    void ProjectComponentsTableHeaderView::ChangeCheckState(Qt::CheckState state)
    {
        if (m_checkState != state)
        {
            m_checkState = state;
            update();
        }
    }

    void ProjectComponentsTableHeaderView::mousePressEvent(QMouseEvent * e)
    {
        if (e)
        {
            int32_t col = logicalIndexAt(e->pos());
            if (col == COL_CHECKBOX)
            {
                m_bMousePressedOnCheckBox = true;
                return;
            }
        }

        QHeaderView::mousePressEvent(e);
    }

    void ProjectComponentsTableHeaderView::mouseReleaseEvent(QMouseEvent * e)
    {
        if (e)
        {
            int32_t col = logicalIndexAt(e->pos());
            if (col == COL_CHECKBOX)
            {
                if (m_bMousePressedOnCheckBox)
                {
                    if (m_checkState == Qt::CheckState::PartiallyChecked)
                    {
                        m_checkState = Qt::CheckState::Checked;
                    }
                    else if (m_checkState == Qt::CheckState::Checked)
                    {
                        m_checkState = Qt::CheckState::Unchecked;
                    }
                    else
                    {
                        m_checkState = Qt::CheckState::Checked;
                    }

                    update();
                    emit CheckStateChanged(m_checkState);

                    m_bMousePressedOnCheckBox = false;
                    return;
                }
            }
        }

        QHeaderView::mouseReleaseEvent(e);
        m_bMousePressedOnCheckBox = false;
    }

    void ProjectComponentsTableHeaderView::paintSection(QPainter * painter, const QRect & rect, int logicalIndex) const
    {
        if (orientation() == Qt::Horizontal)
        {
            QFont font;
            font.setFamily("Microsoft YaHei");
            font.setPixelSize(12);

            DBG_WARN_AND_RETURN_VOID_UNLESS(model(), L"model()为空", L"GMEP", L"2024-01-30");
            switch (logicalIndex)
            {
            case COL_CHECKBOX:
            {
                painter->save();

                // draw background
                painter->fillRect(rect, QBrush(QColor(217, 221, 228, 255)));

                // draw border
                painter->setPen(QPen(QColor(189, 199, 213, 255), 1.0));
                painter->drawLine(rect.topLeft(), rect.topRight());
                painter->drawLine(rect.bottomLeft(), rect.bottomRight());

                // 若无checkbox， 只绘制背景色
                if (!m_isEditOperationVisible)
                    break;

                // draw checkbox
                int32_t boxExtent = 12;
                QPoint boxOffset((rect.width() - boxExtent) / 2, (rect.height() - boxExtent) / 2);
                QRect boxRect(rect.topLeft() + boxOffset, QSize(boxExtent, boxExtent));

                if (m_checkState == Qt::CheckState::Unchecked)
                {
                    PaintingUtils::DrawBorder(painter, boxRect, QMargins(1, 1, 1, 1), QMargins(2, 2, 2, 2), QColor(189, 199, 213, 255));
                }
                else if (m_checkState == Qt::CheckState::Checked)
                {
                    PaintingUtils::DrawBorder(painter, boxRect, QMargins(1, 1, 1, 1), QMargins(2, 2, 2, 2), QColor(82, 145, 221, 255), QColor(82, 145, 221, 255));

                    QRect tickRect = boxRect.marginsAdded(QMargins(-2, -2, -2, -2));
                    QImage tickImage = QImage(":/images/icon_tick_ffffff_12.png");
                    painter->setRenderHint(QPainter::RenderHint::SmoothPixmapTransform);
                    painter->drawPixmap(tickRect, QPixmap::fromImage(tickImage));
                }
                else if (m_checkState == Qt::CheckState::PartiallyChecked)
                {
                    PaintingUtils::DrawBorder(painter, boxRect, QMargins(1, 1, 1, 1), QMargins(2, 2, 2, 2), QColor(82, 145, 221, 255));

                    QRect squareRect = boxRect.marginsRemoved(QMargins(2, 2, 2, 2));
                    painter->fillRect(squareRect, QBrush(QColor(82, 145, 221, 255), Qt::BrushStyle::SolidPattern));
                }

                painter->restore();

                break;
            }
            case COL_COMPONENT_NAME:
            {
                painter->save();

                // draw background
                painter->fillRect(rect, QBrush(QColor(217, 221, 228, 255)));

                // draw border
                painter->setPen(QPen(QColor(189, 199, 213, 255), 1.0));
                painter->drawLine(rect.topLeft(), rect.topRight());
                painter->drawLine(rect.bottomLeft(), rect.bottomRight());

                // draw text
                QString text = model()->headerData(logicalIndex, orientation(), Qt::DisplayRole).value<QString>();
                if (!text.isEmpty())
                {
                    QMargins textMargin(10, 0, 0, 0);
                    QRect textRect = rect.adjusted(textMargin.left(), textMargin.top(), -textMargin.right(), -textMargin.bottom());
                    
                    painter->setFont(font);
                    painter->setPen(QPen(QColor(0, 0, 0, 255), 1.0));
                    QTextOption textOption(Qt::AlignLeft | Qt::AlignVCenter);
                    textOption.setWrapMode(QTextOption::WrapMode::NoWrap);
                    painter->drawText(textRect, text, textOption);
                }

                painter->restore();

                break;
            }
            case COL_COMPONENT_OPERARION_SYNC:
            case COL_COMPONENT_OPERARION_PLACE:
            case COL_COMPONENT_OPERARION_LOADINTO:
            case COL_COMPONENT_OPERARION_DELETE:
            {
                QRect joinedRect = rect.adjusted(0, 0, 0, 0);

                painter->save();

                // draw background
                painter->fillRect(joinedRect, QBrush(QColor(217, 221, 228, 255)));

                // draw border
                painter->setPen(QPen(QColor(189, 199, 213, 255), 1.0));
                painter->drawLine(joinedRect.topLeft(), joinedRect.topRight());
                painter->drawLine(joinedRect.bottomLeft(), joinedRect.bottomRight());

                // draw text
                QString text = model()->headerData(logicalIndex, orientation(), Qt::DisplayRole).value<QString>();
                if (!text.isEmpty())
                {
                    QMargins textMargin(0, 0, 0, 0);
                    QRect textRect = joinedRect.adjusted(textMargin.left(), textMargin.top(), -textMargin.right(), -textMargin.bottom());

                    painter->setFont(font);
                    painter->setPen(QPen(QColor(0, 0, 0, 255), 1.0));
                    int textAlignment = model()->headerData(logicalIndex, orientation(), Qt::ItemDataRole::TextAlignmentRole).value<int>();
                    QTextOption textOption((Qt::AlignmentFlag)textAlignment);
                    textOption.setWrapMode(QTextOption::WrapMode::NoWrap);
                    painter->drawText(textRect, text, textOption);
                }

                painter->restore();

                break;
            }
            default:
            {
                QHeaderView::paintSection(painter, rect, logicalIndex);
                break;
            }
            }
        }
        else
        {
            QHeaderView::paintSection(painter, rect, logicalIndex);
        }
    }
}
